home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / misc / emu / arosdev.lha / AROS / workbench / c / shell.c < prev    next >
C/C++ Source or Header  |  1997-01-27  |  7KB  |  379 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: shell.c,v 1.12 1997/01/27 00:22:38 ldp Exp $
  4.  
  5.     Desc:
  6.     Lang: english
  7. */
  8. #include <exec/memory.h>
  9. #include <exec/libraries.h>
  10. #include <proto/exec.h>
  11. #include <dos/dosextens.h>
  12. #include <dos/rdargs.h>
  13. #include <proto/dos.h>
  14. #include <utility/tagitem.h>
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <aros/debug.h>
  18.  
  19. BPTR cLock;
  20.  
  21. static void printpath(void)
  22. {
  23.     BPTR dir;
  24.     STRPTR buf;
  25.     ULONG i;
  26.     dir=CurrentDir(0);
  27.     for(i=256;;i+=256)
  28.     {
  29.     buf=AllocVec(i,MEMF_ANY);
  30.     if(buf==NULL)
  31.         break;
  32.     if(NameFromLock(dir,buf,i))
  33.     {
  34.         FPuts(Output(),buf);
  35.         FreeVec(buf);
  36.         break;
  37.     }
  38.     FreeVec(buf);
  39.     }
  40.     CurrentDir(dir);
  41. }
  42.  
  43. static void prompt(void)
  44. {
  45.     printpath();
  46.     FPuts(Output(),"> ");
  47.     Flush(Output());
  48. }
  49.  
  50. struct linebuf
  51. {
  52.     BPTR file;
  53.     UBYTE *buf;
  54.     ULONG size;
  55.     ULONG bend;
  56.     ULONG lend;
  57.     LONG eof;
  58. };
  59.  
  60. static LONG readline(struct linebuf *lb)
  61. {
  62.     if(lb->bend)
  63.     {
  64.     UBYTE *src=lb->buf+lb->lend, *dst=lb->buf;
  65.     ULONG i=lb->bend-lb->lend;
  66.     if(i)
  67.         do
  68.         *dst++=*src++;
  69.         while(--i);
  70.     lb->bend-=lb->lend;
  71.     }
  72.     lb->lend=0;
  73.     for(;;)
  74.     {
  75.     LONG subsize;
  76.     for(;lb->lend<lb->bend;)
  77.         if(lb->buf[lb->lend++]=='\n')
  78.         {
  79.         lb->buf[lb->lend-1]='\0';
  80.         return 0;
  81.         }
  82.     if(lb->eof)
  83.     {
  84.         FreeVec(lb->buf);
  85.         lb->buf=NULL;
  86.         lb->eof=0;
  87.         return 0;
  88.     }
  89.     if(lb->bend>=lb->size)
  90.     {
  91.         UBYTE *newbuf;
  92.         newbuf=AllocVec(lb->size+256,MEMF_ANY);
  93.         if(newbuf==NULL)
  94.         {
  95.         FreeVec(lb->buf);
  96.         lb->buf=NULL;
  97.         return ERROR_NO_FREE_STORE;
  98.         }
  99.         CopyMem(lb->buf,newbuf,lb->bend);
  100.         FreeVec(lb->buf);
  101.         lb->buf=newbuf;
  102.         lb->size+=256;
  103.     }
  104.     subsize=Read(lb->file,lb->buf+lb->bend,lb->size-lb->bend);
  105.     if(subsize==0)
  106.     {
  107.         if(lb->bend)
  108.         lb->buf[lb->bend++]='\n';
  109.         lb->eof=1;
  110.     }else if(subsize<0)
  111.     {
  112.         /*ada 30.8.96 This is a REALLY BAD hack !! */
  113.         if (IoErr() != -1 && IoErr() != 0)
  114.         {
  115.         ULONG error = IoErr();
  116.  
  117.         VPrintf ("Shell:Read %ld\n", &error);
  118.         PrintFault(IoErr(), "Shell:Read");
  119.         FreeVec(lb->buf);
  120.         lb->buf=NULL;
  121.         return IoErr();
  122.         }
  123.     }else
  124.         lb->bend+=subsize;
  125.     }
  126. }
  127.  
  128. BPTR loadseg(STRPTR name)
  129. {
  130.     BPTR old, *cur, seg;
  131.     STRPTR s;
  132.     seg=LoadSeg(name);
  133.     if(seg)
  134.     return seg;
  135.     s=name;
  136.     while(*s)
  137.     {
  138.     if(*s==':'||*s=='/')
  139.         return 0;
  140.     s++;
  141.     }
  142.     old=CurrentDir(0);
  143.     cur=(BPTR *)BADDR(Cli()->cli_CommandDir);
  144.     while(cur!=NULL)
  145.     {
  146.     (void)CurrentDir(cur[1]);
  147.     seg=LoadSeg(name);
  148.     if(seg)
  149.         break;
  150.     cur=(BPTR *)BADDR(cur[0]);
  151.     }
  152.     if (!seg)
  153.     {
  154.     (void)CurrentDir(cLock);
  155.     seg=LoadSeg(name);
  156.     }
  157.     CurrentDir(old);
  158.     return seg;
  159. }
  160.  
  161. LONG execute(STRPTR com)
  162. {
  163.     STRPTR s1=NULL, s2=NULL;
  164.     STRPTR args, rest, command=NULL, infile=NULL, outfile=NULL, appfile=NULL;
  165.     STRPTR last;
  166.     BPTR in=0, out=0;
  167.     BPTR seglist, lock;
  168.     struct FileInfoBlock *fib;
  169.     LONG res, size, error=0;
  170.     struct CSource cs;
  171.  
  172.     last=com;
  173.     while(*last++)
  174.     ;
  175.     args=s1=(STRPTR)AllocVec(last-com+1,MEMF_ANY);
  176.     rest=s2=(STRPTR)AllocVec(last-com+1,MEMF_ANY);
  177.     if(args==NULL||rest==NULL)
  178.     {
  179.     error=ERROR_NO_FREE_STORE;
  180.     goto end;
  181.     }
  182.  
  183.     cs.CS_Buffer=com;
  184.     cs.CS_Length=last-com-1;
  185.     cs.CS_CurChr=0;
  186.  
  187.     for(;;)
  188.     {
  189.     while(com[cs.CS_CurChr]==' '||com[cs.CS_CurChr]=='\t')
  190.         *rest++=com[cs.CS_CurChr++];
  191.     if(com[cs.CS_CurChr]==';')
  192.         break;
  193.     if(command==NULL)
  194.         command=args;
  195.     else if(com[cs.CS_CurChr]=='<')
  196.     {
  197.         cs.CS_CurChr ++; /* Skip redirection character */
  198.         infile=args;
  199.     }
  200.     else if(com[cs.CS_CurChr]=='>')
  201.     {
  202.         cs.CS_CurChr ++; /* Skip redirection character */
  203.  
  204.         if(com[cs.CS_CurChr]=='>')
  205.         {
  206.         cs.CS_CurChr ++; /* Skip redirection character */
  207.         appfile=args;
  208.         }
  209.         else
  210.         outfile=args;
  211.     }
  212.     else
  213.     {
  214.         size=cs.CS_CurChr;
  215.         res=ReadItem(args,~0ul/2,&cs);
  216.         while(size<cs.CS_CurChr)
  217.         *rest++=com[size++];
  218.         if(res==ITEM_NOTHING||res==ITEM_ERROR)
  219.         {
  220.         *rest++=0;
  221.         break;
  222.         }
  223.         continue;
  224.     }
  225.     res=ReadItem(args,~0ul/2,&cs);
  226.     if(res!=ITEM_QUOTED&&res!=ITEM_UNQUOTED)
  227.         break;
  228.     while(*args++)
  229.         ;
  230.     }
  231.     if(command==NULL||!*command)
  232.     goto end;
  233.     if(infile!=NULL)
  234.     {
  235.     in=Open(infile,MODE_OLDFILE);
  236.     if(!in)
  237.     {
  238.         infile=NULL;
  239.         error=IoErr();
  240.         goto end;
  241.     }
  242.     in=SelectInput(in);
  243.     }
  244.     if(outfile!=NULL)
  245.     {
  246.     out=Open(outfile,MODE_NEWFILE);
  247.     if(!out)
  248.     {
  249.         outfile=NULL;
  250.         error=IoErr();
  251.         goto end;
  252.     }
  253.     out=SelectOutput(out);
  254.     }
  255.     if(out==NULL && appfile!=NULL)
  256.     {
  257.     out=Open(appfile,MODE_OLDFILE);
  258.     if(!out)
  259.     {
  260.         outfile=NULL;
  261.         error=IoErr();
  262.         goto end;
  263.     }
  264.     Seek (out,0,OFFSET_END);
  265.     out=SelectOutput(out);
  266.     }
  267.     seglist=loadseg(command);
  268.     if(seglist)
  269.     {
  270.     last=s2;
  271.     while(*last++)
  272.         ;
  273.     RunCommand(seglist,100000,s2,last-s2-1);
  274.     UnLoadSeg(seglist);
  275.     }else if(infile==NULL&&outfile==NULL)
  276.     {
  277.     lock=Lock(command,SHARED_LOCK);
  278.     if(lock)
  279.     {
  280.         fib=AllocDosObject(DOS_FIB,NULL);
  281.         if(fib!=NULL)
  282.         {
  283.         if(Examine(lock,fib))
  284.         {
  285.             if(fib->fib_DirEntryType>0)
  286.             lock=CurrentDir(lock);
  287.             else
  288.             SetIoErr(error=ERROR_OBJECT_WRONG_TYPE);
  289.         }
  290.         FreeDosObject(DOS_FIB,fib);
  291.         }
  292.         UnLock(lock);
  293.     }
  294.     else
  295.         error = IoErr ();
  296.     }
  297.  
  298. end:
  299.     if(in)
  300.     Close(SelectInput(in));
  301.     if(out)
  302.     Close(SelectOutput(out));
  303.     FreeVec(s1);
  304.     FreeVec(s2);
  305.     if(error)
  306.     PrintFault(error,"Couldn't run command");
  307.     Flush(Output());
  308.     return 0;
  309. }
  310.  
  311. int executefile(STRPTR name)
  312. {
  313.     struct linebuf lb = { 0, NULL, 0, 0, 0, 0 };
  314.     LONG error=0;
  315.  
  316.     lb.file=Open(name,MODE_OLDFILE);
  317.     if(lb.file)
  318.     {
  319.     for(;;)
  320.     {
  321.         error=readline(&lb);
  322.         if(error||lb.buf==NULL)
  323.         break;
  324.         error = execute(lb.buf);
  325.         if (error != 0)
  326.         PrintFault (error, "execute:");
  327.     }
  328.     Close(lb.file);
  329.     }else
  330.     error=IoErr();
  331.     return error;
  332. }
  333.  
  334. int main (int argc, char ** argv)
  335. {
  336.     struct RDArgs *rda;
  337.     STRPTR args[2]={ "S:Shell-Startup", NULL };
  338.     struct linebuf lb = { 0, NULL, 0, 0, 0, 0 };
  339.     LONG error=0;
  340.  
  341.     lb.file=Input();
  342.  
  343.     cLock = Lock("C:", SHARED_LOCK);
  344.     if (!cLock)
  345.     {
  346.     PrintFault (IoErr(), "Shell");
  347.     return RETURN_ERROR;
  348.     }
  349.  
  350.     rda=ReadArgs("FROM,COMMAND/K/F",(IPTR *)args,NULL);
  351.     if(rda!=NULL)
  352.     {
  353.     if(args[1])
  354.         execute((STRPTR)args[1]);
  355.     else
  356.     {
  357.         ULONG num=((struct Process *)FindTask(NULL))->pr_TaskNum;
  358.         VPrintf("New Shell process %ld\n",&num);
  359.         Flush(Output());
  360.         executefile((STRPTR)args[0]);
  361.         for(;;)
  362.         {
  363.         prompt();
  364.         error=readline(&lb);
  365.         if(error||lb.buf==NULL)
  366.             break;
  367.         execute(lb.buf);
  368.         }
  369.         VPrintf("Process %ld ending\n",&num);
  370.         Flush(Output());
  371.     }
  372.     FreeArgs(rda);
  373.     }
  374.  
  375.     UnLock (cLock);
  376.  
  377.     return 0;
  378. }
  379.